#include "knx_facade.h"

#include "knx/bau07B0.h"
#include "knx/bau27B0.h"
#include "knx/bau57B0.h"

#include "knx/bits.h"
#include "knx/group_object_table_object.h"
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>

#include "fdsk.h"

volatile sig_atomic_t loopActive = 1;
void signalHandler(int sig) {
  (void)sig;

  // can be called asynchronously
  loopActive = 0;
}

bool sendHidReport(uint8_t *data, uint16_t length) { return false; }
bool isSendHidReportPossible() { return false; }

#if MASK_VERSION == 0x57B0
KnxFacade<LinuxPlatform, Bau57B0> knx;
#elif MASK_VERSION == 0x27B0
KnxFacade<LinuxPlatform, Bau27B0> knx;
#elif MASK_VERSION == 0x07B0
KnxFacade<LinuxPlatform, Bau07B0> knx;
#else
#error Mask version not supported yet!
#endif

#define GO_SCREEN_BRIGHTNESS knx.getGroupObject(1)

void onScreenBrightness(GroupObject &go) {
  printf("onScreenBrightness: %d\n", go.value());
}

void setup() {
  srand((unsigned int)time(NULL));
  knx.readMemory();
  if (knx.configured()) {
    GO_SCREEN_BRIGHTNESS.dataPointType(DPT_Value_1_Ucount);
    GO_SCREEN_BRIGHTNESS.callback(onScreenBrightness);
    printf("screen default brightness: %d\n", knx.paramByte(0));
  }
  if (knx.individualAddress() == 0)
    knx.progMode(true);
  knx.start();
}

int main(int argc, char **argv) {
  printf("main() start.\n");

  uint8_t serialNumber[] = {0x00, 0xFA, 0x01, 0x02, 0x03, 0x04};
  uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                   0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};

  FdskCalculator calc;
  char fdskString[42]; // 6 * 6 chars + 5 dashes + nullbyte = 42
  calc.snprintFdsk(fdskString, sizeof(fdskString), serialNumber, key);
  printf("FDSK: %s\n", fdskString);

  // Prevent swapping of this process
  struct sched_param sp;
  memset(&sp, 0, sizeof(sp));
  sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
  sched_setscheduler(0, SCHED_FIFO, &sp);
  mlockall(MCL_CURRENT | MCL_FUTURE);

  // Register signals
  signal(SIGINT, signalHandler);
  signal(SIGTERM, signalHandler);

  knx.platform().cmdLineArgs(argc, argv);

  setup();
  knx.progMode(true);
  while (loopActive) {
    knx.loop();
    delayMicroseconds(100);
  }
  printf("main() exit.\n");
}
